package org.smarthings.things.management.impl;

import java.util.ArrayList;
import java.util.List;

import org.smarthings.things.management.Thing;
import org.smarthings.things.management.ThingAction;
import org.smarthings.things.management.ThingProperty;
import org.smarthings.things.management.metadata.provider.ThingActionMetadataProvider;
import org.smarthings.things.management.metadata.provider.ThingPropertyMetadataProvider;

public class ThingBuilder {

	private String name;
	private String type;
	private int state;

	private String[] tags;
	private List<ThingProperty> properties;
	private List<ThingAction> actions;

	private ThingsEventPropagator thingsEventPropagator;
	private ThingPropertyMetadataProvider thingsPropertyMetadataProvider;
	private ThingActionMetadataProvider thingsActionMetadataProvider;

	private ThingBuilder(ThingsEventPropagator thingsEventPropagator,
			ThingPropertyMetadataProvider thingsPropertyMetadataProvider,
			ThingActionMetadataProvider thingsActionMetadataProvider) {
		this.thingsEventPropagator = thingsEventPropagator;
		this.thingsActionMetadataProvider = thingsActionMetadataProvider;
		this.thingsPropertyMetadataProvider = thingsPropertyMetadataProvider;
	}

	public static ThingBuilder create(ThingsEventPropagator thingsEventPropagator,
			ThingPropertyMetadataProvider thingsPropertyMetadataProvider,
			ThingActionMetadataProvider thingsActionMetadataProvider) {
		return new ThingBuilder(thingsEventPropagator, thingsPropertyMetadataProvider,
				thingsActionMetadataProvider);
	}

	public ThingBuilder name(String name) {
		this.name = name;
		return this;
	}

	public ThingBuilder type(String type) {
		this.type = type;
		return this;
	}

	public ThingBuilder state(int state) {
		this.state = state;
		return this;
	}

	public ThingBuilder tags(String[] tags) {
		this.tags = tags;
		return this;
	}

	public ThingBuilder property(String name) {
		if (this.properties == null) {
			this.properties = new ArrayList<ThingProperty>(5);
		}
		ThingProperty property = new ThingPropertyImpl(name,
				thingsPropertyMetadataProvider.getThingPropertyDescription(name),
				thingsEventPropagator);
		this.properties.add(property);
		return this;
	}

	public ThingBuilder properties(String[] names) {
		if (names != null && names.length > 0) {
			if (this.properties == null) {
				this.properties = new ArrayList<ThingProperty>(5);
			}
			for (String name : names) {
				ThingProperty property = new ThingPropertyImpl(name,
						thingsPropertyMetadataProvider.getThingPropertyDescription(name),
						thingsEventPropagator);
				this.properties.add(property);
			}
		}
		return this;
	}

	public ThingBuilder action(String name) {
		if (this.actions == null) {
			this.actions = new ArrayList<ThingAction>(5);
		}
		ThingAction action = new ThingActionImpl(name,
				thingsActionMetadataProvider.getThingActionDescription(name), thingsEventPropagator);
		this.actions.add(action);
		return this;
	}

	public ThingBuilder actions(String[] names) {
		if (names != null && names.length > 0) {
			if (this.actions == null) {
				this.actions = new ArrayList<ThingAction>(5);
			}
			for (String name : names) {
				ThingAction action = new ThingActionImpl(name,
						thingsActionMetadataProvider.getThingActionDescription(name),
						thingsEventPropagator);
				this.actions.add(action);
			}
		}
		return this;
	}

	public Thing build() {
		return new ThingImpl(name, type, tags, properties == null ? null
				: new ThingPropertyCollectionImpl(properties), actions == null ? null
				: new ThingActionCollectionImpl(actions), thingsEventPropagator);

	}

}
